home *** CD-ROM | disk | FTP | other *** search
- //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
- //
- // HSV Demo 2.c
- //
- // Demonstrates drawing with HSV colors and building a CLUT
- // from scratch. Nicer colors than HSV Demo 1 because we're
- // customizing our color environment with our spiffy clut.
- // HSV Demo 1 used a nice but insufficient CLUT provided by
- // the System.
- //
- // Also shows how to use the Process Manager to obtain the
- // name of the application.
- //
- // History:
- //
- // 950225 jb: Written
- // 950305 jb: Cleaned up and commented
- //
- //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
-
-
- // __#Defines________________________________________________________________________
- #define kMainWindowResID 1000
- #define kAppColorTableResID 72 //ID of nice, 256-color palette provided by System
- #define kSleepTicks 0xFFFFFFFF //relinquish all time; don't want null events
-
- // __#Headers________________________________________________________________________
- #include <Palettes.h>
- #include <math.h>
- #include "Utils.h" //for EnviroCheck
-
- // __#Protos_________________________________________________________________________
- // __ Macros_________________________________________________________________________
- // __ Enums__________________________________________________________________________
- // __ Typedefs_______________________________________________________________________
- // __ Static Protos__________________________________________________________________
- static void ToolBoxInit(void);
- static Boolean OpenMainWindow( void );
- static void ShowHSVCircle2( void );
- static void WaitForQuit( void );
- static void GetAppName(char *pascalName);
-
- // __ Extern Globals_________________________________________________________________
- // __ Static Globals_________________________________________________________________
- static OSErr gErr;
- static WindowPtr gMainWindow;
- static Str32 gAppName;
-
- // __ Functions______________________________________________________________________
-
-
-
-
-
- //____ main __________________________________________________________________________
- //
- void main( void )
- {
-
- ToolBoxInit();
-
- if (!EnviroCheck())
- ExitToShell();
-
- GetAppName((char *)gAppName);
-
- if (!OpenMainWindow())
- ExitToShell();
-
- ShowHSVCircle2();
-
- WaitForQuit();
-
- if(NULL != gMainWindow)
- DisposeWindow(gMainWindow);
-
- }//main
-
-
- //____ ToolBoxInit __________________________________________________________________________
- //
- // Basic initialization.
- //
- static void ToolBoxInit( void )
- {
- InitGraf(&qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(NULL);
- InitCursor();
- FlushEvents(everyEvent, 0);
- } //ToolBoxInit
-
-
- //____ OpenMainWindow __________________________________________________________________________
- //
- // Create CLUT from scratch, filling it with customized colors suitable for our
- // nefarious HSV circle-drawing needs. Open a window
- //
- // Open our window, install palette built from a resource CTable.
- // provided by the System.
- //
- // All entries in palette marked pmTolerant, with a tolerance of 0x5000.
- //
- static Boolean OpenMainWindow( void )
- {
- PaletteHandle appPalette; // the palette that we will make the window's palette
- CTabHandle tempColorTable;
- HSVColor ourHSV;
- RGBColor resultingRGB;
- ColorSpecPtr aClrSpec;
- short x;
-
- ourHSV.hue = 0;
- ourHSV.saturation = 65535;
- ourHSV.value = 65535;
-
- //create a CLUT in memory
- tempColorTable = (CTabHandle)NewHandle(sizeof(ColorTable) + (256 * sizeof(ColorSpec)));
- (**tempColorTable).ctSeed = GetCTSeed();
- (**tempColorTable).ctFlags = 0x0;
- (**tempColorTable).ctSize = 255;
- aClrSpec = (**tempColorTable).ctTable;
-
- //make a neutral gray for the background
- resultingRGB.red = resultingRGB.blue = resultingRGB.green = 32768;
- aClrSpec->rgb = resultingRGB;
- aClrSpec++;
-
- //create a rainbow of colors and stuff them into consecutive rgbs in the CLUT.
- for (x = 2; x < 255; x++)
- {
- ourHSV.hue += 65535 / 254;
- HSV2RGB(&ourHSV,&resultingRGB);
- aClrSpec->rgb = resultingRGB;
- aClrSpec++;
- }
-
-
- // create and show the window, make sure it's frontmost
- gMainWindow = GetNewCWindow( kMainWindowResID, ( Ptr )NULL, ( WindowPtr ) -1 );
- if (NULL == gMainWindow) //real apps should handle this gracefully
- return FALSE;
- SetWTitle(gMainWindow,gAppName);
- ShowWindow( gMainWindow );
- SetPort( gMainWindow );
-
- //create a new Palette for our window, passing in tempColorTable and all
- //of its bright, shiny colors
- appPalette = NewPalette( 256, tempColorTable, pmTolerant, 0x0000 );
-
- //pop the new Palette into the window
- NSetPalette( gMainWindow, appPalette, pmAllUpdates );
-
- //tell the hardware that the color for our window's changed and
- //to make sure the colors our Palette is requesting are available.
- ActivatePalette(gMainWindow);
-
- //release memory occupied by our temporary ColorTable.
- DisposeCTable(tempColorTable);
-
- return TRUE;
- }//OpenWindowWithCTableID
-
-
- //____ ShowHSVCircle2 __________________________________________________________________________
- //
- // This is similar to the HSV Demo 1 function:
- //
- // Walk incrementally around the perimeter of the HSV color wheel, creating HSV colors
- // on each step, translating them to RGB, and then drawing a dot with that color
- // on a circle corresponding the color's origin on the HSV wheel.
- //
- // Changing the value of kNumCircles to a number greater than one will cause more HSV
- // circles to be drawn, each of which will exhibit increasing Saturation and Value.
- //
- // However, since we've craftily installed a Palette with the colors we know we'll need,
- // the image rendered is much nicer.
- //
- // Also, note that the string drawn looks nifty as it cycles from color to color. It does,
- // however, have to be drawn every time. Keep this in mind when we explore Palette Animation.
- //
- static void ShowHSVCircle2( void )
- {
- #define kNumSteps 256 //defines how many dots
- #define mThetaStepSize (6.283 / kNumSteps) //how far around our circle to go
- #define mColorStepSize (65535 / kNumSteps) //how far to go around color wheel per dot
- #define kNumCircles 1 // <=== try changing this to values like 5 or 10
- #define kRadius 120 //max radius of our circle
- #define mRadiusStep (kRadius / kNumCircles) //how much to enlarge each circle
- #define mSatValStep (65535 / kNumCircles) //amount to increments saturation and value
- #define kHalfRectSize 20 //halve length to make centering easy
-
- short step;
- short x, y, cenX, cenY;
- double theta;
- Rect aRect;
- short theRadius;
- short circleNum;
- HSVColor ourHSV;
- RGBColor resultingRGB;
-
- TextFont(0); //use Chicago
- TextSize(12);
-
- cenX = qd.thePort->portRect.right / 2;
- cenY = qd.thePort->portRect.bottom / 2;
-
- //use a neutral gray for the background
- resultingRGB.red = resultingRGB.blue = resultingRGB.green = 32768;
- RGBForeColor(&resultingRGB);
- PaintRect(&qd.thePort->portRect);
-
- //start out with full red
- ourHSV.hue = 0;
- ourHSV.saturation = 0;
- ourHSV.value = 0;
- theRadius = 0;
- for (circleNum = 0; circleNum < kNumCircles; circleNum++)
- {
- theRadius += mRadiusStep;
- ourHSV.saturation += mSatValStep;
- ourHSV.value += mSatValStep;
-
- //draw HSV circle
- for (step = 0, theta = 0.0; step < kNumSteps; step++)
- {
- MoveTo(20,20);
- DrawString(gAppName);
- theta += mThetaStepSize;
- x = cenX + theRadius * cos(theta);
- y = cenY - theRadius * sin(theta);
-
- ourHSV.hue += mColorStepSize; //move clockwise along color wheel
- HSV2RGB(&ourHSV,&resultingRGB);
-
- RGBForeColor(&resultingRGB);
-
- SetRect(&aRect, x - kHalfRectSize, y - kHalfRectSize, x + kHalfRectSize, y + kHalfRectSize);
- PaintOval(&aRect);
- }
-
- }//for circleNum
- }//ShowHSVCircle2
-
-
- //____ WaitForQuit __________________________________________________________________________
- //
- // Hangs out until there is any keyboard or mouse activity. A rather plain instance of
- // an event loop; a real program would be more robust.
- //
- static void WaitForQuit( void )
- {
- Boolean wait;
- EventRecord theEvent;
-
- wait = TRUE;
- while (wait)
- {
- if(WaitNextEvent(everyEvent, &theEvent, kSleepTicks, 0L))
- {
- switch (theEvent.what)
- {
- case mouseDown:
- case keyDown:
- wait = FALSE;
- break;
- }//switch (theEvent.what)
- }//if WaitNextEvent
- }//while
-
- }//WaitForQuit
-
-
- //____ GetAppName __________________________________________________________________________
- //
- // This happy function does just what it says. But, instead of using some scary (and
- // soon-to-be obsolete) low memory global to get at the application's name, we use
- // the Process Manager, even if it does force us through a couple of non-intuitive
- // hoops in the, uh, process...
- //
- static void GetAppName(char *pascalName)
- {
- ProcessSerialNumber PSN;
- ProcessInfoRec info;
-
- gErr = GetCurrentProcess(&PSN);
- if (noErr != gErr)
- goto Xit;
-
- //stick stuff into info rec before calling GetProcessInformation
- info.processInfoLength = sizeof( ProcessInfoRec );
- info.processAppSpec = nil;
- info.processName = ( StringPtr ) pascalName;
-
- gErr = GetProcessInformation(&PSN,&info);
- if (noErr != gErr)
- goto Xit;
-
- Xit:
- if (noErr != gErr) //was there an error?
- {
- BlockMove("\8Untitled", pascalName, 9);
- }
-
- return;
-
- }//GetAppName
-